<template>
	<div v-keyboard:s+e+t.press="setKeyboardEvent" class="MyDrawer">
		<div
			v-if="modal"
			class="drawer-back"
			:class="{ showBack: state.open }"
			@click.stop="changeOpenState"
		></div>
		<n-el
			class="drawer-box"
			:class="drawerBoxclassName"
			:style="{ width: defaultWidth }"
			tag="div"
		>
			<n-dropdown
				v-if="showClose && state.drawerIcon"
				:show="state.dropdownState"
				class="drawer-icon-dropdown"
				box-class="drawer-dropdown-tip"
				:placement="`bottom-${direction === 'left' ? 'start' : 'end'}`"
				:options="dropdownOptions"
				show-arrow
				@select="handleSelect"
				@clickoutside="changeDropdownState"
			>
				<div
					v-if="showClose && state.drawerIcon"
					class="drawer-icon-box"
					:class="drawerIconClassName"
				>
					<n-tooltip
						class="item"
						:placement="`${direction === 'left' ? 'right' : 'left'}-start`"
						trigger="hover"
						:disabled="state.tipDisabled"
					>
						<template #trigger>
							<div
								v-keyboard:Esc="escKeyBoardEvent"
								class="drawer-icon"
								@click.stop="changeOpenState"
								@contextmenu.stop.prevent="changeDropdownState"
							>
								<slot v-if="state.open" name="open">
									<n-icon size="34" color="#fff"><CloseOutline /></n-icon>
								</slot>
								<slot v-else name="close">
									<n-icon size="26" color="#fff"><SettingOutlined /></n-icon>
								</slot>
							</div>
						</template>
						<slot name="tooltip">
							<p>支持右键点击：</p>
							<p>1、隐藏按钮功能(支持键盘输入set显隐)</p>
							<p>2、隐藏Tip提示功能</p>
						</slot>
					</n-tooltip>
				</div>
			</n-dropdown>
			<n-scrollbar>
				<div class="drawer-box-body" v-bind="$attrs">
					<slot></slot>
				</div>
			</n-scrollbar>
		</n-el>
	</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
	inheritAttrs: false,
});
</script>

<script lang="ts" setup>
import { computed, onMounted, watch, reactive } from "vue";
import SettingOutlined from "@vicons/antd/SettingOutlined";
import CloseOutline from "@vicons/ionicons5/CloseOutline";
import { location } from "@/util/storage";
import { isMobile } from "@/util/validata";
import { useI18n } from "@/lang";
import { nsToPxPct } from "@/util";
import type { LRDirection } from "@/model/util";

const props = withDefaults(
	defineProps<{
		modelValue?: boolean;
		width?: string | number;
		showClose?: boolean;
		modal?: boolean;
		direction?: LRDirection;
		beforeClose?: (done?: () => void) => void;
		closeOnPressEscape?: boolean;
	}>(),
	{
		modelValue: undefined,
		width: 260,
		showClose: true,
		modal: true,
		direction: "right",
		closeOnPressEscape: true,
	},
);

const emit = defineEmits<{
	(event: "update:modelValue", value: boolean): void;
}>();

const { t: $t } = useI18n();

const state = reactive({
	open: false,
	tipDisabled: false,
	drawerIcon: true,
	dropdownState: false,
});

const dropdownOptions = [
	{
		label: $t("system.hideBtn"),
		key: 0,
	},
	{
		label: () => $t(`system.${state.tipDisabled ? "show" : "hide"}Tip`),
		key: 1,
	},
];

const drawerIconClassName = computed(() => {
	if (!props.showClose) return [];
	return [`${props.direction === "left" ? "drawer-icon-left" : "drawer-icon-right"}`];
});

const drawerBoxclassName = computed(() => {
	const rightClass = `drawer-box-right ${state.open ? "showRight" : "hideRight"}`;
	const leftClass = `drawer-box-left ${state.open ? "showLeft" : "hideLeft"}`;
	return [`${props.direction === "left" ? leftClass : rightClass}`];
});

const defaultWidth = computed(() => nsToPxPct(props.width));

watch(
	() => props.modelValue,
	value => {
		typeof value === "boolean" && value !== undefined && (state.open = value);
	},
);

onMounted(() => {
	const tipValue = location.getItem("global-setting-tip"),
		iconValue = location.getItem("global-setting-icon");
	tipValue !== null && (state.tipDisabled = tipValue);
	iconValue !== null && changeDrawerIcon(iconValue);
});

// 控制右键 下拉菜单
function changeDropdownState(value?: boolean | MouseEvent) {
	state.dropdownState =
		value !== undefined && typeof value === "boolean" ? value : !state.dropdownState;
}
// 控制抽屉
function changeOpenState(value?: boolean | MouseEvent) {
	changeDropdownState(false);
	function changeOpen() {
		if (typeof props.modelValue === "boolean" && props.modelValue !== undefined) {
			emit("update:modelValue", !props.modelValue);
		} else {
			state.open = value !== undefined && typeof value === "boolean" ? value : !state.open;
		}
	}
	if (state.open && props.beforeClose) {
		props.beforeClose(changeOpen);
	} else {
		changeOpen();
	}
}
// 控制抽屉按钮
function changeDrawerIcon(value?: boolean) {
	state.drawerIcon =
		value !== undefined && typeof value === "boolean" ? value : !state.drawerIcon;
	location.setItem("global-setting-icon", state.drawerIcon);
}

// 键盘事件 s+e+t 控制抽屉按钮
function setKeyboardEvent() {
	if (!props.showClose) return;
	if (isMobile()) return;
	changeDrawerIcon();
}
// 键盘事件 esc 关闭抽屉
function escKeyBoardEvent() {
	props.closeOnPressEscape && changeOpenState(false);
}

// 右键下拉事件
function handleSelect(e: number) {
	if (e === 0) {
		changeDrawerIcon();
	} else if (e === 1) {
		state.tipDisabled = !state.tipDisabled;
		location.setItem("global-setting-tip", state.tipDisabled);
	}
	changeDropdownState(false);
}
</script>

<style lang="scss" scoped>
.MyDrawer {
	position: fixed;
	left: 0;
	top: 0;
	z-index: 2000;
}
.drawer-back {
	background-color: rgba(0, 0, 0, 0.3);
	position: fixed;
	left: 0;
	top: 0;
}
.showBack {
	width: 100vw;
	height: 100vh;
}
.drawer-box {
	height: 100vh;
	// background-color: #fff;
	position: fixed;
}
.drawer-box-right {
	right: 0;
}
.drawer-box-left {
	left: 0;
}
.showLeft {
	transform: translate(0%);
	transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
}
.hideLeft {
	transform: translate(-100%);
	transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
}
.showRight {
	transform: translate(0%);
	transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
}
.hideRight {
	transform: translate(100%);
	transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
}
.drawer-icon-box {
	width: 48px;
	height: 48px;
	position: absolute;
	top: 45vh;
	overflow: hidden;
}
:deep(.drawer-dropdown-tip),
.drawer-icon {
	width: 100%;
	height: 100%;
}
.drawer-icon {
	background: #1890ff;
	cursor: pointer;
	display: flex;
	justify-content: center;
	align-items: center;
}
.drawer-icon-right {
	left: -48px;
	border-radius: 6px 0 0 6px !important;
}
.drawer-icon-left {
	right: -48px;
	border-radius: 0 6px 6px 0 !important;
}
.drawer-box-body {
	width: 100%;
	min-height: 100vh;
	background-color: var(--body-color);
}
</style>
